/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brucexx.wedding.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.brucexx.wedding.dao.BaseModelDAO;
import com.brucexx.wedding.model.PicInfo;
import com.brucexx.wedding.model.PicStore;
import com.brucexx.wedding.util.NumberHelper;
import com.brucexx.wedding.util.StringHelper;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;

/**
 * 
 * @author Administrator
 */
@Controller
public class UploadController {

	private static final Log logger = LogFactory.getLog(AdminController.class);
	public final static String PIC_FOLDER = "picfolder";

	/**
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/admin_upload.action", method = RequestMethod.POST)
	public void handleUpload(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		logger.info("开始上传===>");
		try {
			uploadFile(request);
		} catch (Exception e) {
			logger.error("上传文件出错", e);
			response.getWriter().write("上传文件出错");
		}
	}

	/**
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/story_upload.action", method = RequestMethod.POST)
	public void storyUpload(HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		try {
			uploadFile(request);
		} catch (Exception e) {
			logger.error("上传文件出错", e);
			response.getWriter().write("上传文件出错");
		}
	}

	private void deleteSinglePic(String id) {
		long pid = NumberHelper.string2Long(id, -1);
		BaseModelDAO.deleteByID(PicInfo.class, pid);
		BaseModelDAO.deleteByID(PicStore.class, pid);
		logger.info("pic id[" + id + "]被删除");
	}

	@RequestMapping(value = "/admin_del_file.action", method = RequestMethod.GET)
	public void handleFileDelete(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		try {
			response.setContentType("text/xml");
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Cache-Control", "no-cache");
			String action = StringHelper.null2String(request
					.getParameter("action"));
			if (action.equals("batch")) {
				String ids = StringHelper.null2String(request
						.getParameter("ids"));
				logger.info("批量删除id[" + ids + "]");
				String[] idlist = ids.split(",");
				for (String id : idlist) {
					deleteSinglePic(id);
				}
			} else {
				String id = StringHelper
						.null2String(request.getParameter("id"));
				logger.info("单个删除id[" + id + "]");
				deleteSinglePic(id);
			}
			response.getWriter().write("1");
			return;
		} catch (Exception e) {
			response.getWriter().write(e.getMessage());
		}
	}

	@RequestMapping(value = "/upload_ajax_check.action", method = RequestMethod.GET)
	public void handleTypeCheckAjax(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		response.setContentType("text/xml");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		String fileName = StringHelper.null2String(request
				.getParameter("picname"));
		String flag = StringHelper.null2String(request.getParameter("flag"));
		logger.info("检查==> flag[" + flag + "],filename[" + fileName + "]");
		if (isExistFile(fileName, flag)) {
			logger.warn("[" + flag + "/" + fileName + "]已经存在了");
			response.getWriter().write("-1");
			return;
		}
		fileName = fileName.toLowerCase();
		if (!StringHelper.isEmpty(fileName)
				&& (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")
						|| fileName.endsWith(".png")
						|| fileName.endsWith(".gif") || fileName
						.endsWith(".bmp"))) {
			response.getWriter().write("1");
			return;
		} else {
			logger.warn("非法的文件格式[" + fileName + "]");
			response.getWriter().write("0");
			return;
		}
	}

	@RequestMapping(value = "/upload_ajax.action", method = RequestMethod.GET)
	public void handleUploadAjax(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		logger.info("收到文件状态请求===>");
		response.setContentType("text/xml");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		// String action =
		// StringHelper.null2String(request.getParameter("action"));
		if (request.getSession().getAttribute("error") != null) {
			request.getSession().removeAttribute("error");
			response.getWriter().write("上传出错,文件大小超过限制");
		}

		int count = 0;
		FileProcessListener listener = null;
		while ((listener = (FileProcessListener) request.getSession()
				.getAttribute("fileprocessor")) == null && count < 20) {
			count++;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (count == 20) {
			logger.info("等待上传超时");
		} else {
			logger.info("开始获得文件检查");
		}

		if (listener.isCompeleted()
				&& request.getSession().getAttribute("pid") != null) {
			String responseText = "!"
					+ StringHelper.getFileSize(listener.getBytesRead(), null)
					+ ","
					+ StringHelper.getFileSize(listener.getContentLength(),
							null) + "," + listener.getCurSpeed() + ","
					+ listener.getLeftTime() + "," + listener.getPercent()
					+ "," + listener.getTotalTime() + ","
					+ listener.getAvgSpeed() + ","
					+ request.getSession().getAttribute("pid");
			logger.info("返回值:" + responseText);
			request.getSession().removeAttribute("fileprocessor");
			request.getSession().removeAttribute("pid");
			response.getWriter().write(responseText);
		} else {
			String responseText = "_"
					+ StringHelper.getFileSize(listener.getBytesRead(), null)
					+ ","
					+ StringHelper.getFileSize(listener.getContentLength(),
							null) + "," + listener.getCurSpeed() + ","
					+ listener.getLeftTime() + "," + listener.getPercent();
			logger.info("返回值:" + responseText);
			response.getWriter().write(responseText);
		}

	}

	private void uploadFile(HttpServletRequest request) throws Exception {
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload fu = new ServletFileUpload(factory);
		FileProcessListener listener = new FileProcessListener();
		fu.setProgressListener(listener);
		request.getSession().setAttribute("fileprocessor", listener);

		String picdesc = null;
		String picname = null;
		String year = null;
		String month = null;
		String flag = null;
		Blob content = null;

		for (FileItemIterator iter = fu.getItemIterator(request); iter
				.hasNext();) {
			FileItemStream item = iter.next();
			InputStream stream = item.openStream();
			try {
				if (item.isFormField()) {
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					byte[] buffer = new byte[64];
					int len;
					while ((len = stream.read(buffer)) != -1) {
						baos.write(buffer, 0, len);
					}
					String value = new String(baos.toByteArray(), "UTF-8");
					logger.info(item.getFieldName() + "==>" + value);
					if (item.getFieldName().equals("picdesc")) {
						picdesc = value;
					} else if (item.getFieldName().equals("flag")) {
						flag = value;
					} else if (item.getFieldName().equals("year")) {
						year = value;
					} else if (item.getFieldName().equals("month")) {
						month = value;
					}
					baos.close();
				} else {
					content = new Blob(IOUtils.toByteArray(stream));
					picname = StringHelper.getFileName(item.getName());
				}
			} catch (Exception e) {
				logger.error("上传文件出错", e);
			}

		}
		if (StringHelper.isEmpty(flag)) {
			flag = "00";
		}

		logger.info("fileName[" + picname + "],length="
				+ content.getBytes().length);

		if (!StringHelper.isEmpty(picname)) {
			PicInfo picInfo = new PicInfo();
			picInfo.setPicName(picname);
			picInfo.setPicDesc(picdesc);
			picInfo.setYearMonth(year + month);
			picInfo.setGmtCreate(new Date());
			picInfo.setOperator((request.getSession().getAttribute("username") == null ? "匿名"
					: request.getSession().getAttribute("username")).toString());
			picInfo.setFlag(flag);
			BaseModelDAO.addOrUpdate(picInfo);

			long id = picInfo.getId();
			PicStore picStore = new PicStore();
			picStore.setId(id);
			storePic(content, picStore, picInfo, request);
			BaseModelDAO.addOrUpdate(picInfo);
			BaseModelDAO.persistAndGet(picStore);
			logger.info("fileName[" + picname + "]保存成功!");
			request.getSession().setAttribute("pid", id);
		}
	}

	private int[] getOriginalCod(Image img) {
		int w = img.getWidth();
		int h = img.getHeight();
		int ow=600;
		int cod[] = { w, h };
		if (w > h) {
			if (w > ow) {
				float f = w / ow;
				cod[0] = ow;
				cod[1] = (int) ((float) h / f);
			}
		} else {
			if (h > ow) {
				float f = h / ow;
				cod[1] = ow;
				cod[0] = (int) ((float) w / f);
			}
		}
		return cod;
	}

	private void storePic(Blob imgContent, PicStore store, PicInfo picInfo,
			HttpServletRequest request) throws IOException {

		ImagesService imagesService = ImagesServiceFactory.getImagesService();
		Image oriImage = ImagesServiceFactory.makeImage(imgContent.getBytes());
		logger.info("orignalImg=> width:" + oriImage.getWidth() + " height:"
				+ oriImage.getHeight());
		int[] xy = getOriginalCod(oriImage);
		float rate = (float) xy[0] / (float) xy[1];

		Transform oldSize = ImagesServiceFactory.makeResize(xy[0], xy[1]);

		Image img1 = imagesService.applyTransform(oldSize, oriImage);

		logger.info("shortImg=> width:" + img1.getWidth() + " height:"
				+ img1.getHeight() + ",size==>" + img1.getImageData().length);
		if (img1.getImageData().length > 1000 * 1000) {
			BaseModelDAO.deleteByID(PicInfo.class, picInfo.getId());
			request.getSession().setAttribute("error", "1");
			throw new RuntimeException("pic over size");
		}
		store.setShortContent(new Blob(img1.getImageData()));

		Image oriImage1 = ImagesServiceFactory.makeImage(imgContent.getBytes());
		Transform resize1 = ImagesServiceFactory.makeResize(160,
				(int) (160 / rate));
		Image img2 = imagesService.applyTransform(resize1, oriImage1);
		store.setPicSnapShort(new Blob(img2.getImageData()));
		logger.info("snapshot=> width:" + img2.getWidth() + " height:"
				+ img2.getHeight() + ",size==>" + img2.getImageData().length);
		picInfo.setWhRate(rate);

	}

	private boolean isExistFile(String filename, String flag) {
		return BaseModelDAO.executeSqlForList(
				"select   from " + PicInfo.class.getName()
						+ " where picName =='" + filename + "' && flag =='"
						+ flag + "'").size() > 0;
	}
}
